load("@buildifier_prebuilt//:rules.bzl", "buildifier", "buildifier_test", "buildozer_binary")
load("@gazelle//:def.bzl", "gazelle", "gazelle_binary")
load("@rules_go//go:def.bzl", "go_library", "nogo")
load("//src/internal/analyzers/staticcheck:def.bzl", "all_staticcheck_analyzers")  # buildifier: disable=bzl-visibility

licenses(["notice"])

exports_files([
    "LICENSE",
    ".bazelversion",
    "MODULE.bazel",
])

# Configure supported architectures.  Note that some architectures are only supported for tooling
# reasons; you can run protoc Windows, but you can't run Pachyderm or pachctl on Windows.  Which
# tools are available on which architectures is a product of the upstream projects; even though most
# upstream projects are written in Go and could theoretically run anywhere Go can, we still use
# their release binaries so as to not build them with "weird" versions of dependencies that we use
# in Pachyderm and cause unexpected behavior.  Where Pachyderm itself is available is a product
# decision; linux/amd64 and linux/arm64 only.  Where pachctl is available is a product decision;
# linux/amd64, linux/arm64, darwin/amd64, darwin/arm64 only.  We are open to being convinced to make
# different product decisions, of course!

config_setting(
    name = "is_x86_64_linux",
    constraint_values = [
        "@platforms//cpu:x86_64",
        "@platforms//os:linux",
    ],
)

platform(
    name = "x86_64_linux",
    constraint_values = [
        "@platforms//cpu:x86_64",
        "@platforms//os:linux",
    ],
    visibility = ["//:__subpackages__"],
)

config_setting(
    name = "is_aarch64_linux",
    constraint_values = [
        "@platforms//cpu:aarch64",
        "@platforms//os:linux",
    ],
)

platform(
    name = "aarch64_linux",
    constraint_values = [
        "@platforms//cpu:aarch64",
        "@platforms//os:linux",
    ],
    visibility = ["//:__subpackages__"],
)

config_setting(
    name = "is_x86_64_macos",
    constraint_values = [
        "@platforms//cpu:x86_64",
        "@platforms//os:macos",
    ],
)

config_setting(
    name = "is_aarch64_macos",
    constraint_values = [
        "@platforms//cpu:aarch64",
        "@platforms//os:macos",
    ],
)

config_setting(
    name = "is_aarch64",
    constraint_values = [
        "@platforms//cpu:aarch64",
    ],
)

config_setting(
    name = "is_x86_64",
    constraint_values = [
        "@platforms//cpu:x86_64",
    ],
)

# Add gazelle for "bazel run gazelle -- ..."

# gazelle:python_extension disabled
gazelle_binary(
    name = "custom_gazelle_binary",
    languages = [
        "@gazelle//language/go",  # Built-in rule from gazelle for Golang.
        "@gazelle//language/proto",  # Built-in rule from gazelle for Protos.
        "@rules_python_gazelle_plugin//python",  # Use gazelle from rules_python.
        "//src/internal/gazelle/jsonnet",
    ],
    visibility = ["//visibility:public"],
)

# gazelle:prefix github.com/pachyderm/pachyderm/v2
# gazelle:proto disable_global
# gazelle:jsonnet_verbose false
gazelle(
    name = "gazelle",
    build_tags = ["bazel"],
    gazelle = "//:custom_gazelle_binary",
)

# Configure nogo (a linter that runs next to the compiler).
nogo(
    name = "nogo",
    config = "nogo.json",
    visibility = ["//visibility:public"],  # must have public visibility
    deps = all_staticcheck_analyzers + [
        # These are go vet's checks; hard-coded here so that upgrading golang.org/x/tools doesn't
        # add new linters unexpectedly.  Commented-out lines are available passes (bazel query
        # 'kind(go_library, @org_golang_x_tools//go/analysis/passes/...)' | grep -v testdata | grep
        # -v cmd | grep -v internal) but that govet doesn't run (`go tool vet help` explains).
        "@org_golang_x_tools//go/analysis/passes/appends",
        "@org_golang_x_tools//go/analysis/passes/asmdecl",
        "@org_golang_x_tools//go/analysis/passes/assign",
        "@org_golang_x_tools//go/analysis/passes/atomic",
        # "@org_golang_x_tools//go/analysis/passes/atomicalign:atomicalign",
        "@org_golang_x_tools//go/analysis/passes/bools",
        # "@org_golang_x_tools//go/analysis/passes/buildssa:buildssa",
        "@org_golang_x_tools//go/analysis/passes/buildtag",
        # "@org_golang_x_tools//go/analysis/passes/cgocall:cgocall", # not supported by rules_go, apparently
        "@org_golang_x_tools//go/analysis/passes/composite",
        "@org_golang_x_tools//go/analysis/passes/copylock",
        # "@org_golang_x_tools//go/analysis/passes/ctrlflow:ctrlflow",
        # "@org_golang_x_tools//go/analysis/passes/deepequalerrors:deepequalerrors",
        "@org_golang_x_tools//go/analysis/passes/defers",
        "@org_golang_x_tools//go/analysis/passes/directive",
        "@org_golang_x_tools//go/analysis/passes/errorsas",
        # "@org_golang_x_tools//go/analysis/passes/fieldalignment:fieldalignment",
        # "@org_golang_x_tools//go/analysis/passes/findcall:findcall",
        # "@org_golang_x_tools//go/analysis/passes/framepointer:framepointer",
        # "@org_golang_x_tools//go/analysis/passes/httpmux:httpmux",
        "@org_golang_x_tools//go/analysis/passes/httpresponse",
        "@org_golang_x_tools//go/analysis/passes/ifaceassert",
        # "@org_golang_x_tools//go/analysis/passes/inspect:inspect",
        "@org_golang_x_tools//go/analysis/passes/loopclosure",
        "@org_golang_x_tools//go/analysis/passes/lostcancel",
        "@org_golang_x_tools//go/analysis/passes/nilfunc",
        "@org_golang_x_tools//go/analysis/passes/nilness",
        # "@org_golang_x_tools//go/analysis/passes/pkgfact:pkgfact",
        "@org_golang_x_tools//go/analysis/passes/printf",
        # "@org_golang_x_tools//go/analysis/passes/reflectvaluecompare:reflectvaluecompare",
        # "@org_golang_x_tools//go/analysis/passes/shadow:shadow",
        "@org_golang_x_tools//go/analysis/passes/shift",
        "@org_golang_x_tools//go/analysis/passes/sigchanyzer",
        "@org_golang_x_tools//go/analysis/passes/slog",
        # "@org_golang_x_tools//go/analysis/passes/sortslice:sortslice",
        "@org_golang_x_tools//go/analysis/passes/stdmethods",
        "@org_golang_x_tools//go/analysis/passes/stdversion",
        "@org_golang_x_tools//go/analysis/passes/stringintconv",
        "@org_golang_x_tools//go/analysis/passes/structtag",
        "@org_golang_x_tools//go/analysis/passes/testinggoroutine",
        "@org_golang_x_tools//go/analysis/passes/tests",
        "@org_golang_x_tools//go/analysis/passes/timeformat",
        "@org_golang_x_tools//go/analysis/passes/unmarshal",
        "@org_golang_x_tools//go/analysis/passes/unreachable",
        "@org_golang_x_tools//go/analysis/passes/unsafeptr",
        "@org_golang_x_tools//go/analysis/passes/unusedresult",
        # "@org_golang_x_tools//go/analysis/passes/unusedwrite:unusedwrite",
        # "@org_golang_x_tools//go/analysis/passes/usesgenerics:usesgenerics",
    ] + [
        # ineffassign https://github.com/gordonklaus/ineffassign
        "//src/internal/analyzers/ineffassign",
    ] + [
        # wrapcheck https://github.com/tomarrell/wrapcheck (using v2)
        "//src/internal/analyzers/wrapcheck",
    ] + [
        # errcheck https://pkg.go.dev/github.com/kisielk/errcheck/errcheck
        "//src/internal/analyzers/errcheck",
    ] + [
        # depguard https://github.com/OpenPeeDeeP/depguard/tree/v2
        "//src/internal/analyzers/depguard",
    ] + [
        # asasalint https://github.com/alingse/asasalint
        "//src/internal/analyzers/asasalint",
    ] + [
        # asciicheck https://github.com/tdakkota/asciicheck
        "//src/internal/analyzers/asciicheck",
    ] + [
        # bidichk https://github.com/breml/bidichk
        "//src/internal/analyzers/bidichk",
    ] + [
        # goprintffuncname https://github.com/jirfag/go-printf-func-name
        "//src/internal/analyzers/goprintffuncname",
    ] + [
        # exhaustive https://pkg.go.dev/github.com/nishanths/exhaustive
        "//src/internal/analyzers/exhaustive",
    ] + [
        # gofmt -s
        "//src/internal/analyzers/gofmt",
    ],
)

# Buildifier formats all BUILD files in the workspace.
buildifier(
    name = "buildifier",
    exclude_patterns = [
        "./.git/*",
    ],
    mode = "fix",
)

# This test checks that all BUILD files (etc.) are formatted correctly.  Run "bazel run
# //:buildifier" to auto-fix them.
buildifier_test(
    name = "buildifier_test",
    size = "small",
    exclude_patterns = [
        "./.git/*",
    ],
    lint_mode = "warn",
    mode = "diff",
    no_sandbox = True,
    tags = ["style"],
    workspace = "//:MODULE.bazel",
)

# Run the buildozer command.
buildozer_binary(
    name = "buildozer",
)

# go for "go doc" or "go mod tidy"; invoke those as "bazel run go -- mod tidy" or similar.
alias(
    name = "go",
    actual = "@rules_go//go",
)

# An alias for regeneating protos.
alias(
    name = "make_proto",
    actual = "//src/proto:run",
)

go_library(
    name = "pachyderm",
    srcs = ["pachyderm.go"],
    importpath = "github.com/pachyderm/pachyderm/v2",
    visibility = ["//visibility:public"],
)

alias(
    name = "pachctl",
    actual = "//src/server/cmd/pachctl",
)

test_suite(
    name = "privileged_tests",
    tags = ["manual"],
    tests = [
        "//src/server/pfs/cmds:cmds_integration_test",
        "//src/server/pfs/fuse:fuse_test",
    ],
)

# Style tests are style tests that have to be run manually, because they look at a lot of files in
# the workspace.  Hermetic style tests (that depend on a few named files, for example) don't need to
# be added here.  If the original test doesn't have the "manual" tag, you don't need to add it here.
test_suite(
    name = "style_tests",
    tags = [
        "manual",
        "style",
    ],
    tests = [
        ":buildifier_test",
        "//jupyter-extension:gazelle_python_manifest.test",
        "//src/proto:run_test",
    ],
)

# pnpm for running npm commands
alias(
    name = "pnpm",
    actual = "@pnpm//:pnpm",
)
